package org.myorg.v3;

import java.util.Random;

public class FEvolution3 {
	/*
	 * 
	 * @param p_s 选择算子
	 * @param p_c 交叉算子 
	 * @param p_m 变异算子
	 */
	private double ps;
	private double pc;
	private double pm;
	
	
	public FEvolution3(double p_s, double p_c, double p_m) {
		ps = p_s;
		pc = p_c;
		pm = p_m;

	}

	/*
	 * 使用锦标赛的选择算法
	 */
	public void select(FPeople3 p) {
		for (int i = 0; i < p.p_num; i++) {
			if (i == 0 || i == 1) {
				p.putPerson(p.getBest(),i);
			} else {
				int pos1 = (int) (Math.random()*p.p_num);
				int pos2 = (int) (Math.random()*p.p_num);
				if (p.personAt(pos1).fitness > p.personAt(pos2).fitness)
					p.putPerson(p.personAt(pos1), i);
				else
					p.putPerson(p.personAt(pos2), i);
			}

		}
	}

	/*
	 * 平坦交叉
	 */
	public void crossOver(FPeople3 p) {
		for (int i=0; i < (int) (pc*p.p_num); i++) {
			int pos1 = (int) (Math.random()*p.p_num);
			int pos2 = (int) (Math.random()*p.p_num);

			for (int j=0; j < p.getPersons()[0].getLength(); j++){
				if (Math.random() > 0.5) {
					double temp = p.getPersons()[pos1].geneAt(j);
					p.getPersons()[pos1].setGene(j, 
							p.getPersons()[pos2].geneAt(j));
					p.personAt(pos2).setGene(j, temp);
				}
			}
		}
	}

	/*
	 * 高斯变异
	 */
	public void mutation(FPeople3 p) {
		Random r = new Random();
		int gene_l = p.personAt(0).length;

		for(int i = 0; i < (int) (pm*p.p_num); i++) {
			//TODO add the number of mutation
			int pos = (int) (Math.random()*p.p_num);

			for (int j = 0; j < gene_l; j++) {
				//int mut_pos = (int) (Math.random()*p.getPersons()[pos].length);
				double temp = p.personAt(pos).geneAt(j);

				double rand = r.nextGaussian();
/*				float test = (float) (rand*dis*0.1);
				float test2 = (float) Math.min(high, temp + rand*dis*0.1);
				temp = Math.max(Math.min(high, temp + rand*dis*0.1),low);*/
				temp = Math.max(Math.min(1, temp + rand*0.001),0);
				
				if (temp == 0 || temp == 1) {
					temp = Math.random();
				}

				//temp = 3.14*Math.random();

				p.personAt(pos).setGene(j, temp);
			}

		}
	}
}

